/*
 * @Author: cailinxi
 * @Date: 2024-05-08 14:52:21
 * @LastEditTime: 2024-07-04 11:28:26
 * @Description: 游戏主架构，进入热更的游戏界面时初始化的，管理所有重要model或着system，通过该脚本初始化其他游戏物体
 */

using System.Threading;
using Cinemachine;
using Cysharp.Threading.Tasks;
using QFramework;
using Sirenix.OdinInspector;
using Unity.VisualScripting;
using UnityEngine;

public class GameArchitecture : MonoBehaviour
{
    private bool m_Init = false;
    public static IArchitecture Interface
    {
        get;
        private set;
    }
    public static GameArchitecture Instance;
    public Snake Snake;
    public Transform StageRoot;
    public PropSetSystem PropSet;
    public CinemachineConfiner2D confiner2D;
    public CinemachineVirtualCamera VirtualCamera;
    private bool isInit = true;
    private bool isStart = false;

    public Mosaic mosaic;
    public Twir twir;

    private async UniTaskVoid Awake()
    {
        if (m_Init) return;
        Instance = this;
        Interface = GameFramework.Interface;
        m_Init = true;
        MainArchitecture.Interface.GetSystem<UIManager>().OpenUIPanel("UIPanel/UIGameMain/UIGameMain").Forget();

        Interface.GetSystem<Stage>().Snake = Snake;
        Interface.GetSystem<Stage>().StageRoot = StageRoot;
        Interface.GetSystem<Stage>().Confiner2D = confiner2D;
        
        Interface.RegisterSystem(PropSet);
        Interface.RegisterEvent<GameOver>(OnGameOver).UnRegisterWhenGameObjectDestroyed(gameObject);
    }

    private void Update() 
    {
        if(isInit && !isStart)
        {
            if(Input.GetKey(KeyCode.Space))
            {
                Interface.SendEvent(new GameStart());
                isStart = true;
            }
        }
    }

    private void Start()
    {
        Interface.GetSystem<Stage>().InitStage();
    }

    public void OnDestroy()
    {
        Debug.Log("MainArchitecture.OnDestroy");
        Interface.Deinit();
    }

    public void OnGameOver(GameOver gameOverEvent)
    {
        if(gameOverEvent.isSuccess)
        {
            twir.enabled = true;
            mosaic.enabled = false;
            twir.OnGameOver(gameOverEvent);
        }
        else
        {
            twir.enabled = false;
            mosaic.enabled = true;
            mosaic.OnGameOver(gameOverEvent);
        }
    }
}

public class GameFramework : Architecture<GameFramework>
{
    protected override void Init()
    {
        RegisterSystem<Stage>(new Stage());
    }

    public override TModel GetModel<TModel>()
    {
        TModel model = base.GetModel<TModel>();
        if (model == null)
        {
            return MainArchitecture.Interface.GetModel<TModel>();
        }
        return model;
    }

    public override TSystem GetSystem<TSystem>()
    {
        TSystem system = base.GetSystem<TSystem>();
        if (system == null)
        {
            return MainArchitecture.Interface.GetSystem<TSystem>();
        }
        return system;
    }

    public override TUtility GetUtility<TUtility>()
    {
        TUtility utility = base.GetUtility<TUtility>();
        if (utility == null)
        {
            return MainArchitecture.Interface.GetUtility<TUtility>();
        }
        return utility;
    }
}